package com.eagle.epay.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eagle.epay.constant.PayPlatformEnum;
import com.eagle.epay.entity.PayInfo;
import com.eagle.epay.exception.ServiceException;
import com.eagle.epay.service.IPayInfoService;
import com.eagle.epay.service.IPayService;
import com.google.gson.Gson;
import com.lly835.bestpay.config.WxPayConfig;
import com.lly835.bestpay.enums.BestPayPlatformEnum;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.enums.OrderStatusEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.service.BestPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Slf4j
@Service
public class PayServiceImpl implements IPayService {
	@Autowired
	private BestPayService bestPayService;

	@Autowired
	private IPayInfoService payInfoService;

	@Autowired
	private RabbitTemplate rabbitTemplate;

	@Autowired
	private Environment env;


	@Override
	public PayResponse create(String orderId, BigDecimal amount, BestPayTypeEnum payTypeEnum) {
		//写入数据库
		PayInfo payInfo = new PayInfo();
		payInfo.setOrderNo(Long.parseLong(orderId));
		payInfo.setPayAmount(amount);
		payInfo.setPlatformStatus(OrderStatusEnum.NOTPAY.name());
		payInfo.setPayPlatform(PayPlatformEnum.getByBestPayTypeEnum(payTypeEnum).getCode());
		payInfoService.save(payInfo);

		//发起支付
		PayRequest payRequest = new PayRequest();
		payRequest.setPayTypeEnum(payTypeEnum);
		payRequest.setOrderId(orderId);
		payRequest.setOrderName("7156503-飞的测试");
		payRequest.setOrderAmount(amount.doubleValue());
		PayResponse resp = this.bestPayService.pay(payRequest);
		return resp;
	}

	@Override
	public String asyncNotify(String notifyData) {
		//1. 签名校验
		PayResponse payResponse = this.bestPayService.asyncNotify(notifyData);
		log.info("异步通知 response={}", notifyData);
		log.info("异步通知封装 payResponse={}", payResponse);

		//2. 金额校验（从数据库查订单）
		//比较严重（正常情况下是不会发生的）发出告警：钉钉、短信
		QueryWrapper<PayInfo> wrapper = new QueryWrapper<>();
		long orderId = Long.parseLong(payResponse.getOrderId());
		wrapper.eq("order_no", orderId);
		PayInfo payInfo = payInfoService.getOne(wrapper);
		if (payInfo == null) {
			//告警
			throw new ServiceException("通过orderNo查询到的结果是null");
		}
		//如果订单支付状态不是"已支付"
		if(!StringUtils.equals(payInfo.getPlatformStatus(),OrderStatusEnum.SUCCESS.name())){
			if (payInfo.getPayAmount().compareTo(BigDecimal.valueOf(payResponse.getOrderAmount())) != 0) {
				//告警
				throw new ServiceException("异步通知中的金额和数据库里的不一致，orderNo=" + payResponse.getOrderId());
			}
		}
//		3. 修改订单
		payInfo.setPlatformStatus(OrderStatusEnum.SUCCESS.name());
		payInfo.setPlatformNumber(payResponse.getOutTradeNo());
		payInfo.setUpdateTime(null);
		payInfoService.updateById(payInfo);

		//TODO 异步发送消息，修改订单状态(将支付这块独立出去作为单独项目)
		rabbitTemplate.convertAndSend(env.getProperty("epay.rabbitmq.fanout.exchange.name"),"",
				new Gson().toJson(payInfo));
//		4. 通知wx
		if (payResponse.getPayPlatformEnum() == BestPayPlatformEnum.WX) {

			//4. 告诉微信不要再通知了
			return "<xml>\n" +
					"  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
					"  <return_msg><![CDATA[OK]]></return_msg>\n" +
					"</xml>";
		}else if (payResponse.getPayPlatformEnum() == BestPayPlatformEnum.ALIPAY) {
			return "success";
		}
		throw new ServiceException("异步通知中错误的支付平台");
	}


	public PayInfo queryByOrderId(String orderId) {
		log.info("查询支付记录...");
		QueryWrapper<PayInfo> wrapper = new QueryWrapper<>();
		wrapper.eq("order_no", Long.parseLong(orderId));
		return payInfoService.getOne(wrapper);

	}
}
